#include "key.h"
#include "systime.h"
#include "button.h"

//#define KEY_LONG_PRESS_TIME     10000UL  //单位Ms
#define KEY_LONG_PRESS_TIME     6000UL  //单位Ms
#define KEY_CLICK_VALID_TIME    100UL    //单位ms 单击按键有效的最小时间，单位ms


typedef enum{
    KEY_STA_INIT,
    KEY_STA_DET,
    KEY_STA_CONFIRM,
    KEY_STA_RELEASE,
}KEY_STA_E;


static struct{
    KEY_STA_E   key_state;
    uint8_t     click_flag;
    uint8_t     press_flag;
    KEY_SW     key_sw;   //按键使能开关，TRUE:开 FALSE:关
}key_ctrl;


static uint32_t get_time_ms(timestamp_t start,timestamp_t end);


void key_init(void)
{
    key_ctrl.key_state = KEY_STA_INIT;
    key_ctrl.click_flag = FALSE;
    key_ctrl.press_flag = FALSE;
    key_ctrl.key_sw = KEY_DISABLE;
}

//使能/失能按键功能  KEY_DISABLE/KEY_ENABLE
void set_key_switch(KEY_SW sw)
{
    key_ctrl.key_sw = sw;
    
    if(key_ctrl.key_sw == KEY_DISABLE){
        key_ctrl.click_flag = FALSE;
        key_ctrl.press_flag = FALSE;
    }
}


void key_task(void)
{
    static timestamp_t     startRtb,endRtb;
    static uint32_t   press_ms; 
    
    switch(key_ctrl.key_state){
        case KEY_STA_INIT:
            if(is_btn_available()){
                key_ctrl.key_state = KEY_STA_DET;
            }
            break;
        case KEY_STA_DET:
            if(btn_get_status()){ //按下
                get_current_systime(&startRtb);
                key_ctrl.key_state = KEY_STA_CONFIRM;
            }
            break;
        case KEY_STA_CONFIRM:
            if(btn_get_status()){
                get_current_systime(&endRtb);
                press_ms = get_time_ms(startRtb,endRtb);
                if(press_ms >= KEY_LONG_PRESS_TIME)
                {
                    if(KEY_ENABLE == key_ctrl.key_sw){
                        key_ctrl.press_flag = TRUE; //长按处理
                    }
                    key_ctrl.key_state = KEY_STA_RELEASE;
                }
            }else{
                get_current_systime(&endRtb);
                press_ms = get_time_ms(startRtb,endRtb);
                if(press_ms >= KEY_CLICK_VALID_TIME){
                    if(KEY_ENABLE == key_ctrl.key_sw){
                        key_ctrl.click_flag = TRUE;
                    }
                }
                key_ctrl.key_state = KEY_STA_DET;
            
            }
            break;
        case KEY_STA_RELEASE:
            if(!btn_get_status()){
                key_ctrl.key_state = KEY_STA_DET;
            }
            break;
        
        default:
            break;
    
    
    }

}

static uint32_t get_time_ms(timestamp_t start,timestamp_t end)
{
    uint32_t time = 0;
    
    if(end.sec < start.sec)
    {
//        printf("key.c ERROR:the time is error");
        return 0;
    }
    
    if((end.sec == start.sec) && (end.msec < start.msec)){
//        printf("key.c ERROR:the time is error");
        return 0;
    }
    
    if(end.msec >= start.msec)
    {
        time = (end.sec - start.sec)*1000 + (end.msec - start.msec);
    }else{
        time = (end.sec - start.sec -1)*1000 + (1000 - start.msec + end.msec);
    }
    return time;
}


uint8_t is_key_click(void)
{
    if(key_ctrl.click_flag == TRUE){
        key_ctrl.click_flag = FALSE;
        return TRUE;
    }
    
    return FALSE;
}

uint8_t is_key_long_press(void)
{
    if(key_ctrl.press_flag == TRUE){
        key_ctrl.press_flag = FALSE;
        return TRUE;
    }
    
    return FALSE;

}

